package util

import (
	"bytes"
	"encoding/base64"
	"github.com/golang/freetype"
	"github.com/gomodule/redigo/redis"
	"image"
	"image/color"
	"image/jpeg"
	"math/rand"
	"os"
	"strings"
	"ubt-rbac-service/internal/core/logger"
)

// NewImage 生成图片
func NewImage(dx, dy int) string {
	// 新建一个 指定大小的 RGBA位图
	img := image.NewNRGBA(image.Rect(0, 0, dx, dy))
	// 画背景
	for y := 0; y < dy; y++ {
		for x := 0; x < dx; x++ {
			img.Set(x, y, color.White)
		}
	}
	// 绘制随机字符
	if fontBytes, err := os.ReadFile("/home/ubt/apps/programs/ubt-rbac/static/ace.ttf"); err == nil {
		if font, err1 := freetype.ParseFont(fontBytes); err1 == nil {
			chars := "afghjkmnpqrstvxy23456789"
			charsLen := len(chars)
			x := 5
			var curChar, codes string
			for i := 0; i < 5; i++ {
				cont := freetype.NewContext()
				cont.SetDPI(72)
				cont.SetFont(font)
				cont.SetFontSize(25)
				cont.SetClip(img.Bounds())
				cont.SetDst(img)
				curColor := getRandColor()
				cont.SetSrc(image.NewUniform(curColor))
				pt := freetype.Pt(x, rand.Intn(10)+25) // 字出现的位置
				x += 20
				randIndex := rand.Intn(charsLen)
				curChar = chars[randIndex : randIndex+1]
				codes += curChar
				_, _ = cont.DrawString(curChar, pt)
			}
			// 将验证码字符中存入缓冲数据库中
			curIp := IpAddr()
			if curIp != "" {
				curIp = strings.Replace(curIp, ".", "", -1)
				curIp = "code" + curIp
			} else {
				curIp = "code127001"
			}
			rdsConn := GetRdsConn()
			defer CloseConn(rdsConn)
			if _, err = redis.String(rdsConn.Do("GET", curIp)); err == nil {
				_, _ = rdsConn.Do("DEL", curIp)
			}
			if _, err = rdsConn.Do("SET", curIp, codes); err == nil {
				// 设置失效时间（1小时）
				if _, err = rdsConn.Do("EXPIRE", curIp, 300); err != nil {
					logger.Error("设置缓冲数据失效时间失败。" + err.Error())
				}
			} else {
				logger.Error("写入缓冲数据失败。" + err.Error())
			}
			return img2Base642(img)
		} else {
			logger.Error(err)
		}
	} else {
		logger.Error(err)
	}
	return ""
}

// img2Base64 图片转Base64
func img2Base642(img image.Image) string {
	emptyBuff := bytes.NewBuffer(nil)
	err := jpeg.Encode(emptyBuff, img, nil)
	if err == nil {
		dist := make([]byte, 50000)
		base64.StdEncoding.Encode(dist, emptyBuff.Bytes())
		index := bytes.IndexByte(dist, 0)
		return string(dist[0:index])
	}
	return ""
}

// getRandColor 随机颜色
func getRandColor() color.RGBA {
	c := uint8(rand.Intn(128))
	m := uint8(rand.Intn(128))
	y := uint8(rand.Intn(128))
	k := uint8(rand.Intn(255))
	return color.RGBA{R: c, G: m, B: y, A: k}
}

// GetSysCode 获取系统图形验证码
func GetSysCode() string {
	curIp := IpAddr()
	if curIp != "" {
		curIp = strings.Replace(curIp, ".", "", -1)
		curIp = "code" + curIp
	} else {
		curIp = "code127001"
	}
	rdsConn := GetRdsConn()
	defer CloseConn(rdsConn)
	if sysCode, err := redis.String(rdsConn.Do("GET", curIp)); err == nil {
		return sysCode
	} else {
		return ""
	}
}
